package com.gmail.dengtao.joe.group.channel.impl;

import com.gmail.dengtao.joe.commons.util.StringUtils;
import com.gmail.dengtao.joe.group.channel.Channel;
import com.gmail.dengtao.joe.group.channel.ChannelListener;
import com.gmail.dengtao.joe.group.interceptor.InterceptorStack;
import com.gmail.dengtao.joe.group.member.MembershipListener;
import com.gmail.dengtao.joe.group.transport.ChannelReceiver;
import com.gmail.dengtao.joe.group.transport.ChannelSender;

abstract class AbstractChannel implements Channel {

	private final Object openLock = new Object();
	private final Object closeLock = new Object();
	protected boolean open = false; // Mark whether channel is open.
	protected boolean close = false;
	protected String id = StringUtils.EMPTY;

	protected ChannelSender channelSender;
	protected ChannelReceiver channelReceiver;

	// listeners
	protected MembershipListener membershipListener;
	protected ChannelListener channelListener;

	protected InterceptorStack interceptorStack = null;

	public boolean isClose() {
		synchronized (closeLock) {
			return close;
		}
	}

	protected void setClose(boolean close) {
		synchronized (closeLock) {
			this.close = close;
		}
	}

	public boolean isOpen() {
		synchronized (openLock) {
			return open;
		}
	}

	protected void setOpen(boolean open) {
		synchronized (openLock) {
			this.open = open;
		}
	}

	@Override
	public void setId(String id) {
		this.id = id;
	}

	@Override
	public String getId() {
		return id;
	}

	@Override
	public InterceptorStack getInterceptorStack() {
		return interceptorStack;
	}

	@Override
	public void setMembershipListener(MembershipListener membershipListener) {
		if (membershipListener == null) {
			throw new IllegalArgumentException(
					"MembershipListener can't be null!");
		}
		this.membershipListener = membershipListener;
		if (interceptorStack != null) {
			interceptorStack.setMembershipListener(membershipListener);
		}
	}

	@Override
	public ChannelSender getChannelSender() {
		return channelSender;
	}

	@Override
	public ChannelReceiver getChannelReceiver() {
		return channelReceiver;
	}

	@Override
	public void setChannelListener(ChannelListener channelListener) {
		if (channelListener == null) {
			throw new IllegalArgumentException("ChannelListener can't be null!");
		}
		this.channelListener = channelListener;
		if (interceptorStack != null) {
			interceptorStack.setChannelListener(channelListener);
		}
	}

}
